from string import ascii_letters, digits

from re import search

from hashlib import md5
from random import choice, randint

from socket import socket

import optparse

class MyParser(optparse.OptionParser):
	def __init__(self, *args, **kwargs):
		description = "Get login and password at http://login.gamespyid.com/"
		optparse.OptionParser.__init__(self, *args, description=description, **kwargs)
		self.add_option('-l', '--login', dest='login', 
			help="GameSpyID Login", type=str)
		self.add_option('-p', '--password', dest='password', 
			help="GameSpyID Password", type=str)

def calculateResponse(login, password, cc, sc):
	pwmd5 = md5(password).hexdigest()
	return md5(
			pwmd5+
			" "*48+
			login+
			cc+
			sc+
			pwmd5).hexdigest()
			
def getTicket(login, password):
	host = "gpcm.gamespy.com"
	port = 29900
	bufsize = 2048
	
	sock = socket()
	sock.connect((host,port))
	serverChallenge = search('(?<=\\\\challenge\\\\).*?(?=\\\\)', sock.recv(bufsize)).group(0)
	clientChallenge = "".join([choice(ascii_letters+digits) for x in xrange(32)])
	sock.sendall("\\login\\\\challenge\\%s\\uniquenick\\%s\\response\\%s\\port\\%s\\namespaceid\\1\\id\\1\\final\\"
		%(
		clientChallenge, 
		login,
		calculateResponse(login, password, clientChallenge, serverChallenge),
		randint(0,32767)
		))
	try:
		return search('(?<=\\\\lt\\\\).*?(?=\\\\)', sock.recv(bufsize)).group(0)
	except AttributeError:
		raise Exception("Something went wrong.")
	
	
def main():
	parser = MyParser()
	(options, args) = parser.parse_args()
	
	if options.login is None or options.password is None:
		parser.error("Either login or password isn't set. Try --help.")
	
	print getTicket(options.login, options.password)
if __name__ == "__main__":
	main()